function ListView(div, cfg) {

	var self = this;
	this.map = {};
	this.items = new Array();
	this.selectedItem = null;
	var c = {
		width: 180,
		height: 250,
		autoSelect: false,
		cookie: 'itemId',
        listTitle: '',
		editTitle: 'Редактирование',
        listDiv: 'itemsList',
        contextMenuDiv: 'itemsContextMenu',
        updateDialogDiv: 'itemsUpdateDialog',
        inputDiv: 'newItem',
        createBtnDiv: 'createItemBtn',
        createItemFn: function(name) {},
		updateItemFn: function(id, name) {},
		removeItemFn: function(id) {},
        onSelect: null
	};
	for(var property in cfg) {
		c[property] = cfg[property];
	}
	var updateDialog = new InputDialog(c.updateDialogDiv, function(name) {
		if(self.selectedItem.name !== name) {
			c.updateItemFn(self.selectedItem.id, name);
		}
	});

	this.init = function() {
		var html = '<table class="table-layout">' +
			'<tr><td colspan="2" align="center"><b>' + c.listTitle + '</b></td></tr>' +
			'<tr><td colspan="2"><div id="' + c.listDiv + '"></div>' +
								'<div id="' + c.contextMenuDiv + '"></div>' +
								'<div id="' + c.updateDialogDiv + '"></div></td></tr>' +
			'<tr><td><input id="' + c.inputDiv + '" type="text"/></td>' +
				'<td><input id="' + c.createBtnDiv + '" type="button" value="Создать"/></td></tr>' +
			'</table>';
		$(div).html(html);

		el(c.inputDiv).jqxInput({ width: 100, height: 22 });
		var btnTimer = null;
		el(c.inputDiv).keydown(function(event) {
			if(event.keyCode === 13) {
				var newItem = el(c.inputDiv).val();
				if(isNotEmpty(newItem)) {
					self.createItem(newItem);
				}
			} else {
				if (btnTimer != null) {
					clearTimeout(btnTimer);
				}
				btnTimer = setTimeout(function () {
					var newItem = el(c.inputDiv).val();
					el(c.createBtnDiv).jqxButton({ disabled: !isNotEmpty(newItem) });
					btnTimer = null;
				}, 200);
			}
		});
		el(c.inputDiv).jqxInput('focus');
		el(c.createBtnDiv).jqxButton({ width: 70, disabled: true });
		el(c.createBtnDiv).on('click', function () {
			var newItem = el(c.inputDiv).val();
			if(isNotEmpty(newItem)) {
				self.createItem(newItem);
			}
		});
		updateDialog.init();

		el(c.listDiv).jqxListBox({ width: c.width, height: c.height, displayMember: 'name', valueMember: 'id' });
		el(c.listDiv).on('change', function(event) {
			if(event.args) {
				var item = event.args.item;
				if (item) {
					var itemObj = self.map[item.value];
					if (itemObj) {
                        var notify = !areSame(self.selectedItem, itemObj);
						self.selectedItem = itemObj;
						$.jqx.cookie.cookie(c.cookie, itemObj.id);
                        if(notify && c.onSelect != null) {
                            c.onSelect(self.selectedItem);
                        }
					}
				}
			}
		});

		el(c.contextMenuDiv).jqxMenu({ width: 100, height: 56, autoOpenPopup: false, mode: 'popup',
			source: [
				{ "id": "1", "label": "Изменить" },
				{ "id": "2", "label": "Удалить" } ]
		});

		el(c.contextMenuDiv).on('itemclick', function (event) {
			var choice = event.args.id;
			switch (choice) {
				case "1":
					updateDialog.show(c.editTitle, self.selectedItem.name);
					break;
				case "2":
					c.removeItemFn(self.selectedItem.id);
					break;
				default :
					break;
			}
		});

		// disable the default browser's context menu.
		$(document).on('contextmenu', function (e) {
			if ($(e.target).parents('.jqx-listbox').length > 0) {
				return false;
			}
			return true;
		});
		return this;
	};

	this.createItem = function(name) {
		c.createItemFn(name);
		el(c.inputDiv).val(null);
		el(c.createBtnDiv).jqxButton({ disabled: true });
	};

	this.attachContextMenu = function(contextMenu) {
		var items = el(c.listDiv).jqxListBox('getItems');
		$.each(items, function(index, item) {
			$(item.element).on('mousedown', function(event) {
				var rightClick = isRightClick(event);
				if (rightClick && event.target != null) {
					el(c.listDiv).jqxListBox('selectItem', item);
					var scrollTop = $(window).scrollTop();
					var scrollLeft = $(window).scrollLeft();
					contextMenu.jqxMenu('open', parseInt(event.clientX) + 5 + scrollLeft, parseInt(event.clientY) + 5 + scrollTop);
					return false;
				}
			});
			$(item.element).bind('dblclick', function(event) {
				updateDialog.show(c.editTitle, self.selectedItem.name);
			});
		});
	};

	this.updateItems = function(items) {
		this.map = {};
		this.items = items;
		var indexToSelect = (c.autoSelect? 0: -1);
		var cookieIdStr = $.jqx.cookie.cookie(c.cookie);
		var cookieId = (cookieIdStr != null)? parseInt(cookieIdStr): null;
		var idToSelect = this.selectedItem != null? this.selectedItem.id: cookieId;
		$.each(items, function(index, item) {
			self.map[item.id] = item;
			if(item.id === idToSelect) {
				indexToSelect = index;
			}
		});

		el(c.listDiv).jqxListBox({ source: items });
		this.attachContextMenu(el(c.contextMenuDiv));

		if(items.length > 0) {
			if(indexToSelect >= 0) {
				el(c.listDiv).jqxListBox('selectIndex', indexToSelect);
			}
		} else {
			this.selectedItem = null;
			if(c.onSelect != null) {
				c.onSelect(null);
			}
		}
	};

	this.selectItem = function(itemId) {
		var indexToSelect = -1;
		$.each(this.items, function(index, item) {
			if(item.id === itemId) {
				indexToSelect = index;
				return false;
			}
		});
		if(indexToSelect >= 0 && indexToSelect !== el(c.listDiv).jqxListBox('getSelectedIndex')) {
			el(c.listDiv).jqxListBox('selectIndex', indexToSelect);
		}
	};
};